home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / TABCTRL.PAK / TABCTRLX.CPP < prev   
C/C++ Source or Header  |  1997-05-06  |  12KB  |  548 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1995, 1996 by Borland International, All Rights Reserved
  4. //
  5. // Sample illustrating the TTabControl class
  6. //----------------------------------------------------------------------------
  7. #include <owl/pch.h>
  8. #include <owl/tabctrl.h>
  9. #include <owl/button.h>
  10. #include <owl/groupbox.h>
  11. #include <owl/radiobut.h>
  12. #include <owl/checkbox.h>
  13. #include <owl/inputdia.h>
  14. #include <owl/notetab.h>
  15. #include <owl/commctrl.h>
  16. #include <stdio.h>
  17. #include "tabctrl.h"
  18.  
  19. //
  20. // Define a few constants
  21. //
  22. const int   TabCtlID  = 0x100;        // ID of the TabControl
  23.  
  24.  
  25. //
  26. // Template to toggle bits on and off
  27. //
  28. template <class T1, class T2>
  29. inline void BitsOnOff(T1& value, T2 bitOn, T2 bitOff)
  30. {
  31.   value |=  bitOn;
  32.   value &= ~bitOff;
  33. }
  34.  
  35. //
  36. //
  37. //
  38. class TNoteTabDlg : public TDialog {
  39.   public:
  40.     TNoteTabDlg(TWindow* parent, TResId id);
  41.  
  42.     void      SetupWindow();
  43.  
  44.   protected:
  45.     TNoteTab* NoteTab;
  46.  
  47.     // Event handlers
  48.     //
  49.     void      TabSelChange(TNotify far&);
  50.     
  51.   DECLARE_RESPONSE_TABLE(TNoteTabDlg);
  52. };
  53.  
  54. DEFINE_RESPONSE_TABLE1(TNoteTabDlg, TDialog)
  55.   EV_TCN_SELCHANGE(IDC_NOTETAB, TabSelChange),
  56. END_RESPONSE_TABLE;
  57.  
  58. char *Tabs[]   = {"Title", "Ship To", "Order Notes"};
  59. int  TitleIDs[]= {IDC_RADIOBUTTON1, IDC_RADIOBUTTON2, IDC_RADIOBUTTON3};
  60. int  ShipIDs[] = {IDC_STATIC1, IDC_EDIT1, IDC_STATIC2, IDC_EDIT2};
  61. int  OrderIDs[]= {IDC_STATIC3, IDC_EDIT3};
  62.  
  63. //
  64. //
  65. //
  66. TNoteTabDlg::TNoteTabDlg(TWindow* parent, TResId id)
  67.             :TDialog(parent, id)
  68. {
  69.   NoteTab = new TNoteTab(this, IDC_NOTETAB);
  70.   NoteTab->SetWindowFace(true);
  71. }
  72.  
  73. //
  74. //
  75. //
  76. void
  77. TNoteTabDlg::SetupWindow()
  78. {
  79.   TDialog::SetupWindow();
  80.   for (int i=0; i<sizeof(Tabs)/sizeof(Tabs[0]); i++)
  81.     NoteTab->Add(Tabs[i]);
  82.   NoteTab->SetSel(0);
  83. }
  84.  
  85. //
  86. //
  87. //
  88. void      
  89. TNoteTabDlg::TabSelChange(TNotify far&)
  90. {
  91.   int index = NoteTab->GetSel(), i;
  92.   for (i=0; i<COUNTOF(TitleIDs); i++) {
  93.     ::ShowWindow(GetDlgItem(TitleIDs[i]), index == 0 ? SW_SHOW : SW_HIDE);
  94.     ::EnableWindow(GetDlgItem(TitleIDs[i]), index == 0 ? TRUE : FALSE);
  95.   }
  96.   for (i=0; i<COUNTOF(ShipIDs); i++) {
  97.     ::ShowWindow(GetDlgItem(ShipIDs[i]), index == 1 ? SW_SHOW : SW_HIDE);
  98.     ::EnableWindow(GetDlgItem(ShipIDs[i]), index == 1 ? TRUE : FALSE); 
  99.   }              
  100.   for (i=0; i<COUNTOF(OrderIDs); i++) {
  101.     ::ShowWindow(GetDlgItem(OrderIDs[i]), index == 2 ? SW_SHOW : SW_HIDE);
  102.     ::EnableWindow(GetDlgItem(OrderIDs[i]), index == 2 ? TRUE : FALSE);
  103.   }              
  104. }
  105.  
  106.  
  107. //
  108. // class TMainWindow
  109. // ~~~~~ ~~~~~~~~~~~
  110. class TMainWindow : public TFrameWindow {
  111.   public:
  112.     TMainWindow(TWindow* clientWnd, bool shrinkToClient = false);
  113.  
  114.   protected:
  115.  
  116.     //
  117.     //
  118.     void      AdjustTabClient();
  119.  
  120.     // Message Handlers
  121.     //
  122.     void          EvSize(uint sizeType, TSize& size);
  123.  
  124.     void          TabSelChange(TNotify far&);
  125.     bool          TabSelChanging(TNotify far&);
  126.     void          TabKeyDown(TTabKeyDown far&);
  127.  
  128.     void          CmNewTab();
  129.     void          CmAddItem();
  130.  
  131.     void          CmRemoveItem();
  132.     void          CeRemoveItem(TCommandEnabler& ce);
  133.  
  134.     void          CmDeleteAll();
  135.     void          CeDeleteAll(TCommandEnabler& ce);
  136.  
  137.     void          CmChangeItem();
  138.     void          CeChangeItem(TCommandEnabler& ce);
  139.  
  140.     void          CmInfo();
  141.  
  142.     void          CmVetoSelChanging();
  143.     void          CeVetoSelChanging(TCommandEnabler& ce);
  144.  
  145.     void          CmShowNoteTab();
  146.  
  147.   public:
  148.     TTabControl*  Tab;
  149.  
  150.   protected:
  151.     bool          VetoSelChanging;
  152.     TWindow*      Client;
  153.  
  154.   DECLARE_RESPONSE_TABLE(TMainWindow);
  155. };
  156.  
  157.  
  158. DEFINE_RESPONSE_TABLE1(TMainWindow, TFrameWindow)
  159.   EV_WM_SIZE,
  160.  
  161.   // Tab Control Notifications
  162.   //
  163.   EV_TCN_SELCHANGE(TabCtlID, TabSelChange),
  164.   EV_TCN_SELCHANGING(TabCtlID, TabSelChanging),
  165.   EV_TCN_KEYDOWN(TabCtlID, TabKeyDown),
  166.  
  167.   // Menu Commands
  168.   //
  169.   EV_COMMAND(CM_NEWTAB,       CmNewTab),
  170.   EV_COMMAND(CM_ADDITEM,      CmAddItem),
  171.  
  172.   EV_COMMAND(CM_REMOVEITEM,   CmRemoveItem),
  173.   EV_COMMAND_ENABLE(CM_REMOVEITEM, CeRemoveItem),
  174.  
  175.   EV_COMMAND(CM_DELETEALL,    CmDeleteAll),
  176.   EV_COMMAND_ENABLE(CM_DELETEALL, CeDeleteAll),
  177.  
  178.   EV_COMMAND(CM_CHANGEITEM,   CmChangeItem),
  179.   EV_COMMAND_ENABLE(CM_CHANGEITEM, CeChangeItem),
  180.  
  181.   EV_COMMAND(CM_INFO,         CmInfo),
  182.   EV_COMMAND(CM_SHOWNOTETAB,  CmShowNoteTab),
  183.  
  184.   EV_COMMAND(CM_VETOSELCHANGING,  CmVetoSelChanging),
  185.   EV_COMMAND_ENABLE(CM_VETOSELCHANGING, CeVetoSelChanging),
  186. END_RESPONSE_TABLE;
  187.  
  188. //
  189. //
  190. //
  191. TMainWindow::TMainWindow(TWindow* clientWnd, bool shrinkToClient)
  192.             :TFrameWindow(0, "Tabs & Notetabs", clientWnd, shrinkToClient),
  193.              VetoSelChanging(false), Tab(0), Client(0)
  194. {
  195. }
  196.  
  197. void
  198. TMainWindow::AdjustTabClient()
  199. {
  200.   // Retrieve pointer to tab control, the client window
  201.   //
  202.   TTabControl* tab = TYPESAFE_DOWNCAST(GetClientWindow(), TTabControl);
  203.   if (tab && tab->GetHandle()) {
  204.  
  205.     // Retrieve the window rectangle of the tab control
  206.     //
  207.     TRect rect;
  208.     tab->GetWindowRect(rect);
  209.  
  210.     // NOTE: GetWindowRect returns screen coordinates... we'll need
  211.     //       to have the coordinates relative to the frame window,
  212.     //       the parent of both the tab and client window
  213.     ::MapWindowPoints(HWND_DESKTOP, *this, (LPPOINT)&rect, 2);
  214.  
  215.     // Ask the tab for it's 'client-area' based in it window location
  216.     //
  217.     tab->AdjustRect(false, rect);
  218.  
  219.     // Move the Client window
  220.     //
  221.     if (Client && Client->GetHandle())
  222.       Client->SetWindowPos(HWND_TOP, rect, SWP_SHOWWINDOW);
  223.   }
  224. }
  225.  
  226. //
  227. //
  228. //
  229. void
  230. TMainWindow::EvSize(uint sizeType, TSize& size)
  231. {
  232.   // Let frame resize the client
  233.   //
  234.   TFrameWindow::EvSize(sizeType, size);
  235.  
  236.   // Adjust the edit control (which is kind of the client of the
  237.   // tab control)...
  238.   //
  239.   AdjustTabClient();
  240. }
  241.  
  242. //
  243. //
  244. //
  245. void
  246. TMainWindow::TabSelChange(TNotify far& /*nm*/)
  247. {
  248. }
  249.  
  250. //
  251. //
  252. //
  253. bool
  254. TMainWindow::TabSelChanging(TNotify far& /*nm*/)
  255. {
  256.   return VetoSelChanging ? 1 : 0;
  257. }
  258.  
  259. //
  260. //
  261. //
  262. void
  263. TMainWindow::TabKeyDown(TTabKeyDown far& /*tk*/)
  264. {
  265.   // NOP
  266. }
  267.  
  268. //
  269. // CmNewTab() creates a dialog which allows the user to select the type
  270. // of TabControl to be created. It then proceeds to create the control
  271. // and makes the new control the client of the application's frame window.
  272. //
  273. void
  274. TMainWindow::CmNewTab()
  275. {
  276.   // Create/Initialize a structure to set and retrieve data;
  277.   //
  278.   struct {
  279.     uint16   buttonStyle;
  280.     uint16   defStyle;
  281.     uint16   singleLine;
  282.     uint16   multipleLine;
  283.   } dlgData = {0, 1, 1, 0};
  284.  
  285.   // Create C++ objects representing the Dialog and its controls
  286.   //
  287.   TDialog* dlg = new TDialog(this, IDD_NEWTAB);
  288.   new TRadioButton(dlg, IDC_RADIOBUTTON1);
  289.   new TRadioButton(dlg, IDC_RADIOBUTTON2);
  290.   new TRadioButton(dlg, IDC_RADIOBUTTON3);
  291.   new TRadioButton(dlg, IDC_RADIOBUTTON4);
  292.  
  293.   // Set the transfer buffer and execute the dialog
  294.   //
  295.   dlg->SetTransferBuffer(&dlgData);
  296.   if (dlg->Execute() == IDOK) {
  297.     // Create a new Tab Control
  298.     //
  299.     TTabControl* tab = new TTabControl(0, TabCtlID, 0, 0, 0, 0);
  300.  
  301.     // Convert selection into style bits
  302.     //
  303.     if (dlgData.defStyle)
  304.       BitsOnOff(tab->Attr.Style, TCS_TABS, TCS_BUTTONS);
  305.     if (dlgData.buttonStyle)
  306.       BitsOnOff(tab->Attr.Style, TCS_BUTTONS, TCS_TABS);
  307.     if (dlgData.singleLine)
  308.       BitsOnOff(tab->Attr.Style, TCS_SINGLELINE, TCS_MULTILINE);
  309.     if (dlgData.multipleLine)
  310.       BitsOnOff(tab->Attr.Style, TCS_MULTILINE, TCS_SINGLELINE);
  311.  
  312.     // Cleanup prior client window
  313.     //
  314.     TWindow* oldClient = SetClientWindow(tab);
  315.     Tab = tab;
  316.     if (oldClient) {
  317.       if (oldClient->GetHandle())
  318.         oldClient->Destroy();
  319.       delete oldClient;
  320.     }
  321.   }
  322. }
  323.  
  324. //
  325. // This function prompts the user for a label and creates a new
  326. // tab item...
  327. //
  328. void
  329. TMainWindow::CmAddItem()
  330. {
  331.   // Prompt user for the label of the tab item
  332.   //
  333.   char lblTxt[80] = {0};
  334.   TInputDialog promptDlg(this, "New Item", "Enter Item Label",
  335.                          lblTxt, sizeof(lblTxt));
  336.   if (promptDlg.Execute() == IDOK) {
  337.     if (lblTxt[0]) {
  338.  
  339.       // Retrieve a pointer to the tab control
  340.       //
  341.       TTabControl* tab = TYPESAFE_DOWNCAST(GetClientWindow(), TTabControl);
  342.  
  343.       // Add a new item to the tabcontrol
  344.       //
  345.       if (tab) {
  346.         TTabItem tabItem(lblTxt);
  347.         tab->Add(tabItem);
  348.  
  349.         // Adjust Client in case the Tab items got rearranged
  350.         //
  351.         AdjustTabClient();
  352.       }
  353.     }
  354.   }
  355. }
  356.  
  357. //
  358. //
  359. //
  360. void
  361. TMainWindow::CeRemoveItem(TCommandEnabler& ce)
  362. {
  363.   ce.Enable((Tab && Tab->GetSel() != -1) ? true : false);
  364. }
  365.  
  366.  
  367. //
  368. // This methods offers the user a list of the tab items and removes
  369. // the selected one (if one is selected via the picklist dialog).
  370. //
  371. void
  372. TMainWindow::CmRemoveItem()
  373. {
  374.   // Prompt user for the label of the tab item
  375.   //
  376.   char indexTxt[80] = {0};
  377.   TInputDialog promptDlg(this, "Remove Item", "Enter Item Index",
  378.                         indexTxt, sizeof(indexTxt));
  379.   if (promptDlg.Execute() == IDOK && indexTxt[0]) {
  380.     // Retrieve a pointer to the tab control
  381.     //
  382.     TTabControl* tab = TYPESAFE_DOWNCAST(GetClientWindow(), TTabControl);
  383.  
  384.     int index = atoi(indexTxt);
  385.  
  386.     // Remove item from tabcontrol
  387.     //
  388.     if (tab) {
  389.       if (index < tab->GetCount() && index >=0) {
  390.         tab->Delete(index);
  391.  
  392.         // Adjust Client in case the Tab items got rearranged
  393.         //
  394.         AdjustTabClient();
  395.       } else {
  396.         MessageBox("Invalid index specified", "INFO");
  397.       }
  398.     }
  399.   }
  400. }
  401.  
  402. //
  403. //
  404. //
  405. void
  406. TMainWindow::CmChangeItem()
  407. {
  408.   int index = Tab->GetSel();
  409.   if (index != -1) {
  410.     char label[80];
  411.     TTabItem item(*Tab, index, TCIF_TEXT, sizeof(label), label);
  412.  
  413.     char prmpt[100];
  414.     sprintf(prmpt, "New label of (%s)", label);
  415.  
  416.     TInputDialog promptDlg(this, "Change Item", prmpt, label, sizeof(label));
  417.     if (promptDlg.Execute() == IDOK) {
  418.       if (label[0]) {
  419.         Tab->SetItem(index, item);
  420.  
  421.         // Adjust Client in case the Tab items got rearranged
  422.         //
  423.         AdjustTabClient();
  424.       }
  425.     }
  426.   }
  427. }
  428.  
  429. //
  430. //
  431. //
  432. void
  433. TMainWindow::CeChangeItem(TCommandEnabler& ce)
  434. {
  435.   ce.Enable((Tab && Tab->GetSel() != -1) ? true : false);
  436. }
  437.  
  438. //
  439. //
  440. //
  441. void
  442. TMainWindow::CmDeleteAll()
  443. {
  444.   TTabControl* tab = TYPESAFE_DOWNCAST(GetClientWindow(), TTabControl);
  445.   if (tab) {
  446.     tab->DeleteAll();
  447.  
  448.     // Adjust Client in case the Tab items got rearranged
  449.     //
  450.     AdjustTabClient();
  451.   }
  452. }
  453.  
  454. //
  455. //
  456. //
  457. void
  458. TMainWindow::CeDeleteAll(TCommandEnabler& ce)
  459. {
  460.   ce.Enable((Tab && Tab->GetCount()) ? true : false);
  461. }
  462.  
  463. //
  464. //
  465. //
  466. void
  467. TMainWindow::CmVetoSelChanging()
  468. {
  469.   VetoSelChanging = !VetoSelChanging;
  470. }
  471.  
  472. //
  473. //
  474. //
  475. void
  476. TMainWindow::CeVetoSelChanging(TCommandEnabler& ce)
  477. {
  478.   ce.SetCheck(VetoSelChanging ? TCommandEnabler::Checked :
  479.                                 TCommandEnabler::Unchecked);
  480. }
  481.  
  482. //
  483. //
  484. //
  485. void TMainWindow::CmInfo()
  486. {
  487.   char infoStr[1024];
  488.   sprintf(infoStr, "Count:%d, RowCount:%d, Sel:%d, ImageList:%08X",
  489.           Tab->GetCount(), Tab->GetRowCount(), Tab->GetSel(), 
  490.           Tab->GetImageList());
  491.   MessageBox(infoStr, "INFO");          
  492. }
  493.  
  494. //
  495. //
  496. //
  497. void          
  498. TMainWindow::CmShowNoteTab()
  499. {
  500.   TNoteTabDlg(this, IDD_NOTETAB).Execute();
  501. }
  502.  
  503.  
  504. //----------------------------------------------------------------------------
  505.  
  506. //
  507. // class TSampleApp
  508. // ~~~~~ ~~~~~~~~~~
  509. // A simple Application Object which simply defines InitMainWindow()
  510. // to initialize the application's frame and client windows.
  511. //
  512. class TSampleApp : public TApplication {
  513.   public:
  514.     void      InitMainWindow();
  515. };
  516.  
  517. //
  518. //
  519. //
  520. void
  521. TSampleApp::InitMainWindow()
  522. {
  523.   // Use tab as client of the main window
  524.   //
  525.   TTabControl* tab = new TTabControl(0, TabCtlID, 0, 0, 0, 0);
  526.  
  527.   // Create frame (with tab as client)
  528.   //
  529.   TMainWindow* frame = new TMainWindow(tab);
  530.   frame->Tab = tab;
  531.  
  532.   SetMainWindow(frame);
  533.   GetMainWindow()->AssignMenu(IDM_APPMENU);
  534.  
  535.   // Enable CTL3D
  536.   //
  537.   EnableCtl3d();
  538. }
  539.  
  540. //
  541. //
  542. //
  543. int
  544. OwlMain(int /*argc*/, char */*argv*/[])
  545. {
  546.   return TSampleApp().Run();
  547. }
  548.